#include "fdfs_api.h"
#include <stdio.h>
#include "make_log.h"
#include "mysql_conn.h"
#include "cfg.h"
#include <sys/time.h>
#include "cJSON.h"
#include "fcgi_stdio.h"
#include <string.h>
#include "utils.h"
#include "mysql_conn.h"
#include <stdlib.h>

static char mysql_user[128] = {0};
static char mysql_pwd[128] = {0};
static char mysql_db[128] = {0};

int get_user_token(char* buf, char* user, char* token);
int get_user_filelist(char* cmd, char* user, int start, int count);
void get_user_files_count(char* user, int ret);
void return_login_status(long num, int token_flag);
int get_fileslist_json_info(char* buf, char* user, char* token, int* p_start, int* p_count);

int main()
{
    char cmd[20] = {0};
    char user[32] = {0};
    char token[32] = {0};

    read_cfg(mysql_user, mysql_pwd, mysql_db);

    while(FCGI_Accept() >= 0)
    {
        printf("Content-type: text/html; charset=utf8\r\n\r\n");

        char* query_string = getenv("QUERY_STRING");

        parse_get_params(query_string, "cmd", cmd, NULL);
        LOG("cmd = %s\n", cmd);

        char buf[4*1024] = {0};
        int ret = 0;
        ret = fread(buf, 1, sizeof(buf), stdin);
        LOG("buf: %s\n", buf);
        if(ret == 0)
        {
            LOG("fread error\n");
            continue;
        }

        if(strcmp(cmd, "count") == 0)
        {
            get_user_token(buf, user, token);
            LOG("user = %s, token = %s", user, token);
            
            ret = verify_token(user, token);
            // if(ret != 0)
            // {
            //     LOG("verify_token error\n");
            //     continue;
            // }

            get_user_files_count(user, ret);
        }
        //获取用户文件信息 127.0.0.1:80/myfiles&cmd=normal
        //按下载量升序 127.0.0.1:80/myfiles?cmd=pvasc
        //按下载量降序127.0.0.1:80/myfiles?cmd=pvdesc
        else
        {
            int start;
            int count;
            get_fileslist_json_info(buf, user, token, &start, &count);
            LOG("user = %s, token = %s, start = %d, count = %d\n", user, token, start, count);

            ret = verify_token(user, token);
            if(ret == 0)
            {
                get_user_filelist(cmd, user, start, count);
            }
            else
            {
                char* out = return_status("111");//token验证失败错误码
                if(out != NULL)
                {
                    printf(out);
                    free(out);
                }
            }
        }
    }
    return 0;
}

int get_user_token(char* buf, char* user, char* token)
{
    int ret = 0;
    cJSON* root = NULL;

    do
    {
        root = cJSON_Parse(buf);
        if(root == NULL)
        {
            LOG("cJSON_Parse error\n");
            ret = -1;
            break;
        }

        cJSON* userName = cJSON_GetObjectItem(root, "user");
        if(NULL == userName)
        {
            LOG("cJSON_GetObjectItem error\n");
            ret = -1;
            break;
        }

        cJSON* token_tmp = cJSON_GetObjectItem(root, "token");
        if(NULL == token_tmp)
        {
            LOG("cJSON_GetObjectItem error\n");
            ret = -1;
            break;
        }

        strcpy(user, userName->valuestring);
        strcpy(token, token_tmp->valuestring);
    }while(0);

    if(root != NULL)
    {
        cJSON_Delete(root);
    }

    return ret;
}

int get_user_filelist(char* cmd, char* user, int start, int count)
{
    int ret = 0;
    char sql_cmd[512] = {0};
    MYSQL* conn = NULL;
    cJSON* root = NULL;
    cJSON* array = NULL;
    char* out = NULL;
    char* out2 = NULL;
    MYSQL_RES* res_set = NULL;

    do
    {
        conn = get_mysql(mysql_user, mysql_pwd, mysql_db);
        if(conn == NULL)
        {
            LOG("get_mysql error\n");
            ret = -1;
            break;
        }

        if(strcmp(cmd, "normal") == 0)
        {
            sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 limit %d, %d", user, start, count);
        }
        else if(strcmp(cmd, "pvasc") == 0)
        {
            sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv asc limit %d, %d", user, start, count);
        }
        else if(strcmp(cmd, "pvdesc") == 0)
        {
            sprintf(sql_cmd, "select user_file_list.*, file_info.url, file_info.size, file_info.type from file_info, user_file_list where user = '%s' and file_info.md5 = user_file_list.md5 order by pv desc limit %d, %d", user, start, count);
        }

        LOG("Sql语句 : %s\n", sql_cmd);

        if(mysql_query(conn, sql_cmd) != 0)
        {
            LOG("mysql_query error: %s\n", mysql_error(conn));
            ret = -1;
            break;
        }

        res_set = mysql_store_result(conn);
        if(res_set == NULL)
        {
            LOG("mysql_store_result error: %s\n", mysql_error(conn));
            ret = -1;
            break;
        }

        int line = 0;
        line = mysql_num_rows(res_set);
        if(line == 0)
        {
            LOG("mysql_num_rows(res_set) failed: %s\n", mysql_error(conn));
            ret = -1;
            break;
        }

        // 将MySQL中查询的结果设置为JSON格式, 然后返回给客户端
        MYSQL_ROW row;

        root = cJSON_CreateObject();
        array = cJSON_CreateArray();

        while((row = mysql_fetch_row(res_set)) != NULL)
        {
            cJSON* item = cJSON_CreateObject();

            int column_index = 1;//           0改成1              1？ 0？
            if(row[column_index] != NULL)
            {
                cJSON_AddStringToObject(item, "user", row[column_index++]);
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddStringToObject(item, "md5", row[column_index++]);
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddStringToObject(item, "create_time", row[column_index++]);
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddStringToObject(item, "file_name", row[column_index++]);
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddNumberToObject(item, "share_status", atoi(row[column_index++]));
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddNumberToObject(item, "pv", atol(row[column_index++]));
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddStringToObject(item, "url", row[column_index++]);
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddNumberToObject(item, "size", atol(row[column_index++]));
            }

            if(row[column_index] != NULL)
            {
                cJSON_AddStringToObject(item, "type", row[column_index++]);
            }

            cJSON_AddItemToArray(array, item);
        }

        cJSON_AddItemToObject(root, "files", array);

        out = cJSON_Print(root);

        // LOG("out = %s\n", out);
        
    }while(0);

    if(ret == 0)
    {
        //成功
        printf("%s", out);
    }
    else
    {
        //失败
        /*
        获取用户文件列表：
            成功：文件列表json
            失败：{"code": "015"}
        */
        out2 = NULL;
        out2 = return_status("015");
    }

    if(out2 != NULL)
    {
        printf(out2);
        free(out2);
    }

    if(res_set != NULL)
    {
        mysql_free_result(res_set);
    }

    if(conn != NULL)
    {
        mysql_close(conn);
    }

    if(root != NULL)
    {
        cJSON_Delete(root);
    }

    if(out != NULL)
    {
        free(out);
    }

    return ret;
}

void get_user_files_count(char* user, int ret)
{
    char sql_cmd[64] = {0};
    long line = 0;
    MYSQL* conn = NULL;

    do
    {
        conn = get_mysql(mysql_user, mysql_pwd, mysql_db);
        if(conn == NULL)
        {
            LOG("get_mysql error\n");
            break;
        }

        sprintf(sql_cmd, "select count from user_file_count where user='%s'", user);
        char tmp[512] = {0};
        //执行sql语句
        //返回值： 0成功并保存记录集，1没有记录集，2有记录集但是没有保存，-1失败
        int ret2 = process_result_one(conn, sql_cmd, tmp);
        if(ret2 != 0)
        {
            LOG("%s failed\n", sql_cmd);
            break;
        }

        line = atol(tmp);
    }while(0);

    if(conn != NULL)
    {
        mysql_close(conn);
    }

    LOG("line = %ld\n", line);

    return_login_status(line, ret);
}

void return_login_status(long num, int token_flag)
{
    char* out = NULL;
    char* token = NULL;
    char num_buf[128] = {0};

    if(token_flag == 0)
    {
        token = "110";//成功
    }
    else
    {
        token = "111";//失败
    }

    sprintf(num_buf, "%ld", num);

    cJSON* root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "num", num_buf);
    cJSON_AddStringToObject(root, "code", token);
    out = cJSON_Print(root);
    cJSON_Delete(root);
    LOG("out: %s\n", out);
    if(out != NULL)
    {
        printf(out);
        free(out);
    }
}

int get_fileslist_json_info(char* buf, char* user, char* token, int* p_start, int* p_count)
{
    int ret = 0;

    /*json数据如下
    {
        "user": "milo"
        "token": xxxx
        "start": 0
        "count": 10
    }
    */
    cJSON* root = NULL;

    do
    {
        root = cJSON_Parse(buf);
        if(NULL == root)
        {
            LOG("cJSON_Parse errro\n");
            ret = -1;
            break;
        }

        cJSON* user_js = cJSON_GetObjectItem(root, "user");
        if(NULL == user_js)
        {
            LOG("user_js error\n");
            ret = -1;
            break;
        }

        cJSON* token_js = cJSON_GetObjectItem(root, "token");
        if(NULL == token_js)
        {
            LOG("token_js error\n");
            ret = -1;
            break;
        }

        cJSON* start_js = cJSON_GetObjectItem(root, "start");
        if(NULL == start_js)
        {
            LOG("start_js error\n");
            ret = -1;
            break;
        }

        cJSON* count_js = cJSON_GetObjectItem(root, "count");
        if(NULL == count_js)
        {
            LOG("count_js error\n");
            ret = -1;
            break;
        }

        strcpy(user, user_js->valuestring);
        strcpy(token, token_js->valuestring);
        *p_start = start_js->valueint;
        *p_count = count_js->valueint;
    }while(0);

    if(root != NULL)
    {
        cJSON_Delete(root);
    }

    return ret;
}